package cc.magicjson.example.demo;

import java.util.Map;
import java.util.Random;
import java.util.stream.IntStream;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.summingLong;

public class MontyHallProblemOptimizing {
    // 可以根据需要调整的门数量 比如100选1
    private static final int DOORS_COUNT = 3;
    private static final int PRIZE_DOOR_COUNT = 1;
    // 模拟实验次数
    private static final int SIMULATIONS = 1000000;
    // 随机数生成器
    private static final Random RANDOM = new Random();

    public static void main(String[] args) {
        // 使用IntStream.range创建一个包含从0到SIMULATIONS-1的所有整数流
        // 对每个模拟实验执行runSimulation方法并映射为Result对象
        // 然后使用groupingBy统计每种结果出现的次数，并用summingLong进行计数
        Map<Result, Long> resultCounts = IntStream.range(0, SIMULATIONS)
                .mapToObj(i -> runSimulation(DOORS_COUNT))
                .collect(groupingBy(result -> result, summingLong(value -> 1L)));
        // 计算“不换门获奖”和“换门获奖”的概率
        double winsByNotSwitching = (double) resultCounts
                .get(Result.WIN_NOT_SWITCHING) / SIMULATIONS * 100;
        double winsBySwitching = (double) resultCounts
                .get(Result.WIN_SWITCHING) / SIMULATIONS * 100;
        // 输出两种策略下获奖的概率
        System.out.println("不换门获奖的概率: " + winsByNotSwitching + "%");
        System.out.println("换门获奖的概率: " + winsBySwitching + "%");
    }

    // 执行一次蒙提霍尔问题模拟，返回结果（不换门赢或换门赢）
    private static Result runSimulation(int doorsCount) {
        // 随机选择一扇门作为奖品门
        int prizeDoorIndex = RANDOM.nextInt(doorsCount);
        // 参赛者随机选择一扇门
        int participantChoiceIndex = RANDOM.nextInt(doorsCount);

        // 如果参赛者最初的选择是奖品门，则视为“不换门赢”
        return participantChoiceIndex == prizeDoorIndex
                ? Result.WIN_NOT_SWITCHING
                : Result.WIN_SWITCHING;
    }

    // 定义枚举类型表示结果：不换门赢或换门赢
    enum Result {
        WIN_NOT_SWITCHING,
        WIN_SWITCHING
    }

}
